package com.handy.database.page;

import java.util.ArrayList;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * 翻页基类,包含翻页的基础算法,其它翻页类继承该类. <br>
 * 默认值:<br>
 * 每页最大显示记录数为20,setMaxLine(20).<br>
 * 页面翻页数量显示最大为10,setPageListCount(10).<br>
 * 
 * 扩展方法:<br>
 * 重写totalRecorder(),recorders()两个函数.<br>
 * 
 * 使用方法:<br>
 * 1.实例化;<br>
 * 2.设置当前显示页 setSpecify(pageNo);<br>
 * 3.设置表名 setTableName("table name");<br>
 * 4.设置查询条件 setFindCondition("where ?=?");<br>
 * 5.设置每页最大显示条数 setMaxLine(20),每页最多显示20条.<br>
 * 6.设置页列表最大值setPageListCount(10),例如当前为第3页，则显示的页列表为1 2 3 4 5 6 7 8 9 10.<br>
 * 7.设置数据库类型.<br>
 * 8.执行query().<br>
 * 9.取记录集recorders.
 * 
 * @author rocken.zeng@gmail.com
 * 
 */
public abstract class AbstractPage {

	public void query() {
		totalRecorder();// 计算总记录数.
		changeCatalog();// 翻页参数.
		setPageLists();// 页列表.
		recorders();// 检索记录.
		if (log.isDebugEnabled()){}
	}

	/**
	 * 查找数据库中符合条件的记录总数.
	 */
	protected abstract void totalRecorder();

	/**
	 * 查找记录操作.
	 */
	protected abstract void recorders();

	/**
	 * 生成页列表如：1 2 3 4 5 6 7 8 9 10,点击可进入相就页. 在changeCatalog()方法之后调用.
	 * 
	 * @param current
	 * @param csum
	 * @return
	 */
	private void setPageLists() {
		int start = 1;
		if (!pages.isEmpty())
			pages.clear();
		if (cPage > pageListCount)
			start = pageListCount
					* (int) Math.ceil((cPage - 1) / pageListCount) + 1;

		cMinPage = start - 1;
		int end = start + pageListCount;
		cMaxPage = end;
		if (end > tPages) {
			end = tPages;
			cMaxPage = 0;
		}

		for (int i = 0; i < pageListCount; i++) {
			if (start <= tPages) {
				pages.add(new Integer(start));
				start++;
			}
		}

	}

	/**
	 * 生成翻页参数. 在query()中获取总记录数后，执行SQL之前调用.
	 */
	private void changeCatalog() {
		// 总页数
		tPages = (int) Math.ceil((double) tCount / maxLine);

		// 当前页
		if (specify == 0) {
			specify = 1;
		}
		if (specify > tPages) {
			specify = tPages;
		}

		// 本页最小记录号
		offset = (specify - 1) * maxLine + 1;
		// offset = (specify - 1) * maxLine;

		// 本页最大记录号
		below = specify * maxLine;

		// 当前页
		cPage = specify;

		// 首页参数
		if (specify > 1) {
			if (pageParam.equals("")) {
				first = "?page=1";
			} else {
				first = "?" + pageParam + "&page=1";
			}
		} else
			first = "";
		// 上页参数
		if (specify > 1)
			if (pageParam.equals("")) {
				prev = "?page=" + (specify - 1);
			} else {
				prev = "?" + pageParam + "&page=" + (specify - 1);
			}
		else
			prev = "";
		// 下页参数
		if (specify < tPages)
			if (pageParam.equals("")) {
				next = "?page=" + (specify + 1);
			} else {
				next = "?" + pageParam + "&page=" + (specify + 1);
			}
		else
			next = "";
		// 未页参数
		if (specify < tPages)
			if (pageParam.equals("")) {
				last = "?page=" + tPages;
			} else {
				last = "?" + pageParam + "&page=" + tPages;
			}
		else
			last = "";
	}

	/**
	 * 设置页面传递参数，如有多个参数要传递，可多次调用.
	 * 
	 * @param key
	 *            参数名
	 * @param value
	 *            参数值
	 */
	public void pageQuery(String key, String value) {
		pageParam += key + "=" + value + "&";
	}

	public String getQuerySQL(){
		return querySQL;		
	}
	protected String querySQL = "";
	private static final Log log = LogFactory.getLog(AbstractPage.class);

	private ArrayList<Object> recorders = new ArrayList<Object>();// 返回数据集.

	private ArrayList<Integer> pages = new ArrayList<Integer>();// 页列表

	private int tCount = 0;// 总记录数.

	private int tPages = 0;// 总页数.

	private int cPage = 0;// 当前页.

	private int cMinPage = 0;// 当前最小页,用于<<.

	private int cMaxPage = 0;// 当前最大页,用于>>.

	private int offset = 0;// 本页最小记录号.

	private int below = 0;// 本页最大记录号.

	private String first = "";// 第一页.

	private String prev = "";// 上一页.

	private String next = "";// 下一页.

	private String last = "";// 最后一页.

	private int specify = 1;// 指定显示页,即当前显示页.

	private int pageListCount = 10;// 所列页总页

	private int maxLine = 20;// 每页最大显示数.

	private String tableName = "";// 所要检索的表名.

	private String columns = "";// 需要查询的字段列表.

	private String findCondition = "";// 查询条件(where,order by 之类的子句).

	private String pageParam = "";// 页面参数.
	
	private int dbKind = 0;//数据库类型.

	/** ********************************************************** */
	/* getXxx();setXxx()****************************************** */
	/** ********************************************************** */

	public ArrayList<Object> getRecorders() {
		return recorders;
	}

	public void setRecorders(ArrayList<Object> recorders) {
		this.recorders = recorders;
	}

	public ArrayList<Integer> getPages() {
		return pages;
	}

	public void setPages(ArrayList<Integer> pages) {
		this.pages = pages;
	}

	public int getTCount() {
		return tCount;
	}

	public void setTCount(int count) {
		tCount = count;
	}

	public int getTPages() {
		return tPages;
	}

	public void setTPages(int pages) {
		tPages = pages;
	}

	public int getCPage() {
		return cPage;
	}

	public void setCPage(int page) {
		cPage = page;
	}

	public int getCMinPage() {
		return cMinPage;
	}

	public void setCMinPage(int minPage) {
		cMinPage = minPage;
	}

	public int getCMaxPage() {
		return cMaxPage;
	}

	public void setCMaxPage(int maxPage) {
		cMaxPage = maxPage;
	}

	public int getOffset() {
		return offset;
	}

	public void setOffset(int offset) {
		this.offset = offset;
	}

	public int getBelow() {
		return below;
	}

	public void setBelow(int below) {
		this.below = below;
	}

	public String getFirst() {
		return first;
	}

	public void setFirst(String first) {
		this.first = first;
	}

	public String getPrev() {
		return prev;
	}

	public void setPrev(String prev) {
		this.prev = prev;
	}

	public String getNext() {
		return next;
	}

	public void setNext(String next) {
		this.next = next;
	}

	public String getLast() {
		return last;
	}

	public void setLast(String last) {
		this.last = last;
	}

	public int getSpecify() {
		return specify;
	}

	public void setSpecify(int specify) {
		this.specify = specify;
	}

	public int getPageListCount() {
		return pageListCount;
	}

	public void setPageListCount(int pageListCount) {
		this.pageListCount = pageListCount;
	}

	public int getMaxLine() {
		return maxLine;
	}

	public void setMaxLine(int maxLine) {
		this.maxLine = maxLine;
	}

	public String getTableName() {
		return tableName;
	}

	public void setTableName(String tableName) {
		this.tableName = tableName;
	}

	public String getColumns() {
		return columns;
	}

	public void setColumns(String columns) {
		this.columns = columns;
	}

	public String getFindCondition() {
		return findCondition;
	}

	public void setFindCondition(String findCondition) {
		this.findCondition = findCondition;
	}

	public String getPageParam() {
		return pageParam;
	}

	public void setPageParam(String pageParam) {
		this.pageParam = pageParam;
	}
	
	public int getDbKind() {
		return dbKind;
	}

	public void setDbKind(int dbKind) {
		this.dbKind = dbKind;
	}

}
